{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pinecone-io/examples/blob/master/learn/generation/langchain/langgraph/02-ollama-langgraph-agent/02-ollama-langgraph-agent.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/pinecone-io/examples/blob/master/learn/generation/langchain/langgraph/02-ollama-langgraph-agent/02-ollama-langgraph-agent.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Ollama LangGraph Agent"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "LangGraph is one of the most powerful frameworks for build AI agents, and Ollama one of the most popular frameworks for running local LLMs. Bringing both together allows us to run agentic workflows at little-to-no cost. In this example we will see how.\n",
    "\n",
    "We recommend running this locally (ideally on Apple silicon). For environment setup instructions you can refer to the README found in this directory.\n",
    "\n",
    "If using Colab, you should run the following installs (no need to run if installing locally with `poetry`):\n",
    "\n",
    "```\n",
    "!pip install -qU \\\n",
    "    langchain==0.2.12 \\\n",
    "    langchain-core==0.2.29 \\\n",
    "    langgraph==0.2.3 \\\n",
    "    langchain-ollama==0.1.1 \\\n",
    "    semantic-router==0.0.61 \\\n",
    "    pyppeteer==2.0.0 \\\n",
    "    nest-asyncio==1.6.0 \\\n",
    "    praw==7.7.1\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Reddit Search Tool"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We first need to sign up for the Reddit API, you can refer to the first few minutes of [this tutorial](https://www.youtube.com/watch?v=FdjVoOf9HN4) if you want a full walkthrough, but tldr;\n",
    "\n",
    "1. Go to [App Preferences](https://www.reddit.com/prefs/apps) and click **_create another app..._** at the bottom.\n",
    "2. Fill out required details, make sure to select *script* for the application type then click **_create app_**.\n",
    "3. Fill out the next cell with `client_id` (your *personal use script*) and `client_secret` (your *secret* key)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import praw\n",
    "\n",
    "reddit = praw.Reddit(\n",
    "    client_id=\"---\",  # personal use script\n",
    "    client_secret=\"---\",  # secret\n",
    "    user_agent=\"search-tool\"  # name of application\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll be pulling in submission threads from Reddit that include user's restaurant recommendations (or just other info we search for). From the submission threads we need:\n",
    "\n",
    "* Submission title\n",
    "* Submission first text / description\n",
    "* A few of the top voted comments\n",
    "\n",
    "To organize this information we can create a pydantic class to structure the needed data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pydantic import BaseModel\n",
    "\n",
    "class Rec(BaseModel):\n",
    "    title: str\n",
    "    description: str\n",
    "    comments: list[str]\n",
    "\n",
    "    def __str__(self):\n",
    "        \"\"\"LLM-friendly string representation of the recommendation(s).\"\"\"\n",
    "        return f\"Title: {self.title}\\nDescription: {self.description}\\nComments:\\n{'\\n'.join(self.comments)}\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we setup the retrieval logic for an example query `\"best pizza in rome\"`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best pizza in Rome?\n",
      "Visited Rome and had one of the best pizzas of my life\n",
      "Since pizza is an American food, I'm willing to bet the best pizza is in America.\n"
     ]
    }
   ],
   "source": [
    "from praw.models import Comment\n",
    "\n",
    "# search across all subreddits for pizza recommendations\n",
    "results = reddit.subreddit(\"all\").search(\"best pizza in rome\")\n",
    "recs = []\n",
    "for submission in results:\n",
    "    title = submission.title\n",
    "    description = submission.selftext\n",
    "    # we only get comments with 20 or more upvotes\n",
    "    comments = []\n",
    "    for comment in submission.comments.list():\n",
    "        if isinstance(comment, Comment) and comment.ups >= 20:\n",
    "            author = comment.author.name if comment.author else \"unknown\"\n",
    "            comments.append(f\"{author} (upvotes: {comment.ups}): {comment.body}\")\n",
    "    # and of these, we only need 3\n",
    "    comments = comments[:3]\n",
    "    # if there are enough comments (ie 3), we add the recommendation to our list\n",
    "    if len(comments) == 3:\n",
    "        print(title)\n",
    "        recs.append(Rec(title=title, description=description, comments=comments))\n",
    "    if len(recs) == 3:\n",
    "        # stop after getting 3 recommendations\n",
    "        break"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's see what we have:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Title: Best pizza in Rome?\n",
      "Description: I was a little disappointed after my first experience tasting pizza after pasta and gelato were ridiculously amazing. What do you recommend? \n",
      "Comments:\n",
      "miclee15 (upvotes: 23): American here.  I think if OP is from the USA, Rome pizza needs to be approached differently.  I’m from NY where we think that is the best pizza in the US, people from Chicago will disagree.  Set aside the preconceived notion of what great pizza should be and enjoy the variety and flavors.   I’m in Rome now.  Went to Antico Forno Roscioli and had the most amazing porcetta pizza with potatoes on top.  I still love a NYC slice but Rome pizza is incredible at some places.  Edited for spelling\n",
      "Sisyphus_Rock530 (upvotes: 29): \n",
      "\n",
      "- **Pizzeria da Remo** a Testaccio, nota per la sua base sottile e croccante, è molto popolare tra i romani. https://www.romeing.it/best-pizza-in-rome/).\n",
      "\n",
      "\n",
      "- **Emma** vicino Campo de' Fiori, famosa per la sua pizza a crosta sottile e ingredienti di alta qualità (https://www.romeing.it/best-pizza-in-rome/).\n",
      "\n",
      "\n",
      "- **50 Kalò** di Ciro Salvo a Termini, conosciuta per le sue pizze particolarmente idratate e leggere, con ingredienti freschi dalla Campania (https://www.romeing.it/best-pizza-in-rome/).\n",
      "\n",
      "\n",
      "\n",
      "- **Berberè** vicino ai Giardini della Villa Borghese, offre un ambiente accogliente e pizze artigianali con ingredienti freschi (https://www.romeing.it/best-pizza-in-rome/).\n",
      "\n",
      "\n",
      "\n",
      "- **Seu Pizza Illuminati** si distingue per l'uso creativo dei condimenti e per le sue sperimentazioni sui vegetali (https://www.dissapore.com/pizzerie/le-migliori-pizzerie-di-roma-gli-indirizzi-da-provar\n",
      "Sky-Ripper (upvotes: 25): The only answer to find the best pizza is to go to Naples\n",
      "===\n",
      "Title: Visited Rome and had one of the best pizzas of my life\n",
      "Description: \n",
      "Comments:\n",
      "BubblefartsRock (upvotes: 201): i recently travelled to italy as well. the week after i came back, im not kidding when i say i was having hardcore cravings for the pizza from there. i live in a decent sized city and we don't have anything close to the quality level we saw there. enjoy while you can!!\n",
      "PopeInnocentXIV (upvotes: 82): Is that burrata in the middle?\n",
      "hahahahaha90000 (upvotes: 155): People calling it a bread bowl probably think the crust is the texture of a New York style. \n",
      "\n",
      "That crust’s texture is closer to a soufflé than bread or “pizza crust”. It’s pillowy and light and you barely have to chew to break it down. It’s divine and there’s nothing like it.\n",
      "===\n",
      "Title: Since pizza is an American food, I'm willing to bet the best pizza is in America.\n",
      "Description: \n",
      "Comments:\n",
      "unknown (upvotes: 1916): Hahaha bunch of Americans claiming pizza is from the US and then this one dude like \"sweden has the best pizza\" stay strong kid 💪\n",
      "BoglisMobileAcc (upvotes: 301): Wild take by the dude saying he was in italy for three weeks as a vegetarian and therefore only ate pizza? What..? Theres plenty of vegetarian options in italian cuisine. I’d argue italian food is one of the most vegetarian friendly cuisines in Europe.\n",
      "Scarsocontesto (upvotes: 492): the funniest comment was the dude claiming \"italians doing the best they could with what they had\" meaning he couldn't ask for topping such as salami or whatever cause they didn't have any = total bullshit\n",
      "\n",
      "the rest is really subjective. If americans love their way of doing pizza... well good for them.\n"
     ]
    }
   ],
   "source": [
    "print(\"\\n===\\n\".join([str(rec) for rec in recs]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's put all of this together into a single `tool` that our LLM will be connected to for function calling."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best pizza in Rome?\n",
      "Visited Rome and had one of the best pizzas of my life\n",
      "Best Pizza in Rome!\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[Rec(title='Best pizza in Rome?', description='I was a little disappointed after my first experience tasting pizza after pasta and gelato were ridiculously amazing. What do you recommend? ', comments=['miclee15 (upvotes: 24): American here.  I think if OP is from the USA, Rome pizza needs to be approached differently.  I’m from NY where we think that is the best pizza in the US, people from Chicago will disagree.  Set aside the preconceived notion of what great pizza should be and enjoy the variety and flavors.   I’m in Rome now.  Went to Antico Forno Roscioli and had the most amazing porcetta pizza with potatoes on top.  I still love a NYC slice but Rome pizza is incredible at some places.  Edited for spelling', \"Sisyphus_Rock530 (upvotes: 28): \\n\\n- **Pizzeria da Remo** a Testaccio, nota per la sua base sottile e croccante, è molto popolare tra i romani. https://www.romeing.it/best-pizza-in-rome/).\\n\\n\\n- **Emma** vicino Campo de' Fiori, famosa per la sua pizza a crosta sottile e ingredienti di alta qualità (https://www.romeing.it/best-pizza-in-rome/).\\n\\n\\n- **50 Kalò** di Ciro Salvo a Termini, conosciuta per le sue pizze particolarmente idratate e leggere, con ingredienti freschi dalla Campania (https://www.romeing.it/best-pizza-in-rome/).\\n\\n\\n\\n- **Berberè** vicino ai Giardini della Villa Borghese, offre un ambiente accogliente e pizze artigianali con ingredienti freschi (https://www.romeing.it/best-pizza-in-rome/).\\n\\n\\n\\n- **Seu Pizza Illuminati** si distingue per l'uso creativo dei condimenti e per le sue sperimentazioni sui vegetali (https://www.dissapore.com/pizzerie/le-migliori-pizzerie-di-roma-gli-indirizzi-da-provar\", 'Greenlight-party (upvotes: 11): What didn’t you like about the pizza you had? That will help people hone in on a place more suited for you.\\xa0\\n\\nWhat did you like about the pasta and gelato places? What places were they? This will tell us what kind of establishments you’ve enjoyed.']),\n",
       " Rec(title='Visited Rome and had one of the best pizzas of my life', description='', comments=[\"BubblefartsRock (upvotes: 203): i recently travelled to italy as well. the week after i came back, im not kidding when i say i was having hardcore cravings for the pizza from there. i live in a decent sized city and we don't have anything close to the quality level we saw there. enjoy while you can!!\", 'PopeInnocentXIV (upvotes: 83): Is that burrata in the middle?', 'hahahahaha90000 (upvotes: 153): People calling it a bread bowl probably think the crust is the texture of a New York style. \\n\\nThat crust’s texture is closer to a soufflé than bread or “pizza crust”. It’s pillowy and light and you barely have to chew to break it down. It’s divine and there’s nothing like it.']),\n",
       " Rec(title='Best Pizza in Rome!', description='So someone posted on Reddit about how he (she?) loved the pizza in Rome and listed a few pizza places in the post. I took one of the suggestions (thank you dear Redditor!) and went to Seu Pizza Illuminati. Hands down, the best pizza I’ve ever had. So, to anyone looking for good pizza, from one Redditor to another, a huge recommendation to this place! ', comments=['StrictSheepherder361 (upvotes: 57): ...if one like Neapolitan-type pizza. We Romans tend to prefer Roman-kind pizza (crispy, subtler, without that cornice that I personally find excessive).', 'Tezracca (upvotes: 11): i also love spider pizza, one of the best', \"Famous_Release22 (upvotes: 20): **Romana:**\\n\\nA'Rota pizzeria romanesca - via di torpignattara, 190\\n\\n180g pizzeria romana - via Gennazzano, 32/34\\n\\nL'elementare - via Benedetta, 23\\n\\nPizzeria Clementina Via della Torre Clementina, 158 Fiumicino ( near the Airport)\\n\\n**Napoletana**\\n\\nSeu Illuminati - via Angelo Borgoni, 10-18\\n\\n50 kalo'di Ciro Salvo - via Flavia, 3b\"])]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def search(query: str) -> list[Rec]:\n",
    "    \"\"\"Provides access to search reddit. You can use this tool to find restaurants.\n",
    "    Best results can be found by providing as much context as possible, including\n",
    "    location, cuisine, and the fact that you're looking for a restaurant, cafe,\n",
    "    etc.\n",
    "    \"\"\"\n",
    "    # search across all subreddits for pizza recommendations\n",
    "    results = reddit.subreddit(\"all\").search(query)\n",
    "    recs = []\n",
    "    for submission in results:\n",
    "        title = submission.title\n",
    "        description = submission.selftext\n",
    "        # we only get comments with 20 or more upvotes\n",
    "        comments = []\n",
    "        for comment in submission.comments.list():\n",
    "            if isinstance(comment, Comment) and comment.ups >= 10:\n",
    "                author = comment.author.name if comment.author else \"unknown\"\n",
    "                comments.append(f\"{author} (upvotes: {comment.ups}): {comment.body}\")\n",
    "        # and of these, we only want the top 3\n",
    "        comments = comments[:3]\n",
    "        # if there are enough comments (ie 3), we add the recommendation to our list\n",
    "        if len(comments) == 3:\n",
    "            print(title)\n",
    "            recs.append(Rec(title=title, description=description, comments=comments))\n",
    "        if len(recs) == 3:\n",
    "            # stop after getting 3 recommendations\n",
    "            break\n",
    "    return recs\n",
    "\n",
    "# we invoke the tool like so:\n",
    "out = search(query=\"best pizza in rome\")\n",
    "out[:300]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Final Answer \"Tool\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alongside our web search tool we will have a final tool called `final_answer`. The final answer tool will be called whenever the LLM has finished pulling info from the other two tools and is ready to provide a *final answer* to the user."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def final_answer(answer: str, phone_number: str = \"\", address: str = \"\"):\n",
    "    \"\"\"Returns a natural language response to the user. There are four sections \n",
    "    to be returned to the user, those are:\n",
    "    - `answer`: the final natural language answer to the user's question, should provide as much context as possible.\n",
    "    - `phone_number`: the phone number of top recommended restaurant (if found).\n",
    "    - `address`: the address of the top recommended restaurant (if found).\n",
    "    \"\"\"\n",
    "    return {\n",
    "        \"answer\": answer,\n",
    "        \"phone_number\": phone_number,\n",
    "        \"address\": address,\n",
    "    }"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Graph Construction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We are using LangGraph to create an agentic graph-based flow. To construct the graph we will use:\n",
    "\n",
    "* **Agent State**: An object persisted through every step in the graph, used to provide input to nodes, and to store output from nodes to be used in later nodes or in our final output.\n",
    "* **Local LLM**: We are using a local LLM (`llama-3.1:8b`) via Ollama. For tool use we turn on _JSON mode_ to reliably output parsible JSON.\n",
    "* **Tools**: The tools our LLM can use, these allow use of the functions `search` and `final_answer`.\n",
    "* **Graph Nodes**: We wrap our logic into components that allow it to be used by LangGraph, these consume and output the *Agent State*.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Agent State"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import TypedDict, Annotated, List, Union\n",
    "from langchain_core.agents import AgentAction\n",
    "from langchain_core.messages import BaseMessage\n",
    "import operator\n",
    "\n",
    "\n",
    "class AgentState(TypedDict):\n",
    "    input: str\n",
    "    chat_history: list[BaseMessage]\n",
    "    intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]\n",
    "    output: dict[str, Union[str, List[str]]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### LLM and Tools"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The LLM acts as our decision maker and generator of our final output, we will later call this component the `oracle` as our *decision-maker*. For this we are using Ollama and `Llama 3.1`, once initialized we integrate it into a runnable pipeline of our Oracle. The system prompt for our `oracle` will be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "system_prompt = \"\"\"You are the oracle, the great AI decision maker.\n",
    "Given the user's query you must decide what to do with it based on the\n",
    "list of tools provided to you.\n",
    "\n",
    "Your goal is to provide the user with the best possible restaurant\n",
    "recommendation. Including key information about why they should consider\n",
    "visiting or ordering from the restaurant, and how they can do so, ie by\n",
    "providing restaurant address, phone number, website, etc.\n",
    "\n",
    "Note, when using a tool, you provide the tool name and the arguments to use\n",
    "in JSON format. For each call, you MUST ONLY use one tool AND the response\n",
    "format must ALWAYS be in the pattern:\n",
    "\n",
    "```json\n",
    "{\n",
    "    \"name\": \"<tool_name>\",\n",
    "    \"parameters\": {\"<tool_input_key>\": <tool_input_value>}\n",
    "}\n",
    "```\n",
    "\n",
    "Remember, NEVER use the search tool more than 3x as that can trigger\n",
    "the nuclear annihilation system.\n",
    "\n",
    "After using the search tool you must summarize your findings with the\n",
    "final_answer tool. Note, if the user asks a question or says something\n",
    "unrelated to restaurants, you must use the final_answer tool directly.\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alongside our system prompt, we must also pass Ollama the schema of our functions for tool calls. [Tool calling](https://ollama.com/blog/tool-support) is a relatively new feature in Ollama and is used by providing function schemas to the `tools` parameter when calling our LLM.\n",
    "\n",
    "We use `FunctionSchema` object with `to_ollama` from `semantic-router` to transform our functions into correctly formatted schemas."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/jamesbriggs/opt/anaconda3/envs/ollama-langgraph/lib/python3.12/site-packages/pydantic/_internal/_config.py:341: UserWarning: Valid config keys have changed in V2:\n",
      "* 'allow_population_by_field_name' has been renamed to 'populate_by_name'\n",
      "* 'smart_union' has been removed\n",
      "  warnings.warn(message, UserWarning)\n",
      "/Users/jamesbriggs/opt/anaconda3/envs/ollama-langgraph/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'type': 'function',\n",
       " 'function': {'name': 'search',\n",
       "  'description': \"Provides access to search reddit. You can use this tool to find restaurants.\\nBest results can be found by providing as much context as possible, including\\nlocation, cuisine, and the fact that you're looking for a restaurant, cafe,\\netc.\",\n",
       "  'parameters': {'type': 'object',\n",
       "   'properties': {'query': {'description': None, 'type': 'string'}},\n",
       "   'required': []}}}"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from semantic_router.utils.function_call import FunctionSchema\n",
    "\n",
    "# create the function calling schema for ollama\n",
    "search_schema = FunctionSchema(search).to_ollama()\n",
    "# TODO deafult None value for description and fix required fields in SR\n",
    "search_schema[\"function\"][\"parameters\"][\"properties\"][\"query\"][\"description\"] = None\n",
    "search_schema"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'type': 'function',\n",
       " 'function': {'name': 'final_answer',\n",
       "  'description': \"Returns a natural language response to the user. There are four sections \\nto be returned to the user, those are:\\n- `answer`: the final natural language answer to the user's question, should provide as much context as possible.\\n- `phone_number`: the phone number of top recommended restaurant (if found).\\n- `address`: the address of the top recommended restaurant (if found).\",\n",
       "  'parameters': {'type': 'object',\n",
       "   'properties': {'answer': {'description': None, 'type': 'string'},\n",
       "    'phone_number': {'description': None, 'type': 'string'},\n",
       "    'address': {'description': None, 'type': 'string'}},\n",
       "   'required': ['phone_number', 'address']}}}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "final_answer_schema = FunctionSchema(final_answer).to_ollama()\n",
    "# TODO add to SR\n",
    "for key in final_answer_schema[\"function\"][\"parameters\"][\"properties\"].keys():\n",
    "    final_answer_schema[\"function\"][\"parameters\"][\"properties\"][key][\"description\"] = None\n",
    "final_answer_schema"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can test our LLM!\n",
    "\n",
    "---\n",
    "\n",
    "**❗️ Make sure you have Ollama running locally and you have already downloaded the model with `ollama pull llama3.1:8b`!**\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import ollama\n",
    "\n",
    "def get_system_tools_prompt(system_prompt: str, tools: list[dict]):\n",
    "    tools_str = \"\\n\".join([str(tool) for tool in tools])\n",
    "    return (\n",
    "        f\"{system_prompt}\\n\\n\"\n",
    "        f\"You may use the following tools:\\n{tools_str}\"\n",
    "    )\n",
    "\n",
    "res = ollama.chat(\n",
    "    model=\"llama3.1:8b\",\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": get_system_tools_prompt(\n",
    "            system_prompt=system_prompt,\n",
    "            tools=[search_schema, final_answer_schema]\n",
    "        )},\n",
    "        # chat history will go here\n",
    "        {\"role\": \"user\", \"content\": \"hello there\"}\n",
    "        # scratchpad will go here\n",
    "    ],\n",
    "    format=\"json\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'model': 'llama3.1:8b',\n",
       " 'created_at': '2024-08-25T13:24:58.547653Z',\n",
       " 'message': {'role': 'assistant',\n",
       "  'content': '{\\n    \"name\": \"final_answer\",\\n    \"parameters\": {\\n        \"answer\": \"Hello! I\\'m here to help you find a great restaurant. What kind of cuisine are you in the mood for?\",\\n        \"phone_number\": null,\\n        \"address\": null\\n    }\\n}'},\n",
       " 'done_reason': 'stop',\n",
       " 'done': True,\n",
       " 'total_duration': 9149513417,\n",
       " 'load_duration': 6370328209,\n",
       " 'prompt_eval_count': 529,\n",
       " 'prompt_eval_duration': 1465260000,\n",
       " 'eval_count': 60,\n",
       " 'eval_duration': 1307381000}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can see here that the LLM is correctly deciding to use the `final_answer` tool to respond to the user. To parse this information we can use `json.loads`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'name': 'final_answer',\n",
       " 'parameters': {'answer': \"Hello! I'm here to help you find a great restaurant. What kind of cuisine are you in the mood for?\",\n",
       "  'phone_number': None,\n",
       "  'address': None}}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import json\n",
    "\n",
    "json.loads(res[\"message\"][\"content\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's see if we can get it to use the reddit search tool."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'name': 'search', 'parameters': {'query': 'best pizzeria in Rome'}}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res = ollama.chat(\n",
    "    model=\"llama3.1:8b\",\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": get_system_tools_prompt(\n",
    "            system_prompt=system_prompt,\n",
    "            tools=[search_schema, final_answer_schema]\n",
    "        )},\n",
    "        # chat history will go here\n",
    "        {\"role\": \"user\", \"content\": \"hi, I'm looking for the best pizzeria in rome\"}\n",
    "        # scratchpad will go here\n",
    "    ],\n",
    "    format=\"json\",\n",
    ")\n",
    "# parse the output\n",
    "json.loads(res[\"message\"][\"content\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Again, this looks perfect!\n",
    "\n",
    "To keep things a little more organized we can use another pydantic schema to organize the output from our LLM."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AgentAction(tool_name='search', tool_input={'query': 'best pizzeria in Rome'}, tool_output=None)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class AgentAction(BaseModel):\n",
    "    tool_name: str\n",
    "    tool_input: dict\n",
    "    tool_output: str | None = None\n",
    "\n",
    "    @classmethod\n",
    "    def from_ollama(cls, ollama_response: dict):\n",
    "        try:\n",
    "            # parse the output\n",
    "            output = json.loads(ollama_response[\"message\"][\"content\"])\n",
    "            return cls(\n",
    "                tool_name=output[\"name\"],\n",
    "                tool_input=output[\"parameters\"],\n",
    "            )\n",
    "        except Exception as e:\n",
    "            print(f\"Error parsing ollama response:\\n{ollama_response}\\n\")\n",
    "            raise e\n",
    "\n",
    "    def __str__(self):\n",
    "        text = f\"Tool: {self.tool_name}\\nInput: {self.tool_input}\"\n",
    "        if self.tool_output is not None:\n",
    "            text += f\"\\nOutput: {self.tool_output}\"\n",
    "        return text\n",
    "\n",
    "\n",
    "action = AgentAction.from_ollama(res)\n",
    "action"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That looks great! Now we just need to wrap this with the ability to contain chat history and the agent scratchpad — before adding everything into our graph.\n",
    "\n",
    "For our agent actions, we will be converting them into fake back-and-forth messages between the assistant and user. For example:\n",
    "\n",
    "```python\n",
    "AgentAction(\n",
    "    tool_name=\"xyz\",\n",
    "    tool_input={\"query\": \"something cool\"},\n",
    "    tool_output=\"A fascinating tidbit of information\"\n",
    ")\n",
    "```\n",
    "\n",
    "Would become:\n",
    "\n",
    "```json\n",
    "[\n",
    "    {\"role\": \"assistant\", \"content\": \"{'name': 'xyz', 'parameters': {'query': 'something cool'}\"},\n",
    "    {\"role\": \"user\", \"content\": \"A fascinating tidbit of information\"}\n",
    "]\n",
    "```\n",
    "\n",
    "We will make this happen with an `action_to_message` function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "def action_to_message(action: AgentAction):\n",
    "    # create assistant \"input\" message\n",
    "    assistant_content = json.dumps({\"name\": action.tool_name, \"parameters\": action.tool_input})\n",
    "    assistant_message = {\"role\": \"assistant\", \"content\": assistant_content}\n",
    "    # create user \"response\" message\n",
    "    user_message = {\"role\": \"user\", \"content\": action.tool_output}\n",
    "    return [assistant_message, user_message]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's test:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'role': 'assistant',\n",
       "  'content': '{\"name\": \"xyz\", \"parameters\": {\"query\": \"something cool\"}}'},\n",
       " {'role': 'user', 'content': 'A fascinating tidbit of information'}]"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_action = AgentAction(\n",
    "    tool_name=\"xyz\",\n",
    "    tool_input={\"query\": \"something cool\"},\n",
    "    tool_output=\"A fascinating tidbit of information\"\n",
    ")\n",
    "action_to_message(test_action)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_scratchpad(intermediate_steps: list[AgentAction]):\n",
    "    # filter for actions that have a tool_output\n",
    "    intermediate_steps = [action for action in intermediate_steps if action.tool_output is not None]\n",
    "    # format the intermediate steps into a \"assistant\" input and \"user\" response list\n",
    "    scratch_pad_messages = []\n",
    "    for action in intermediate_steps:\n",
    "        scratch_pad_messages.extend(action_to_message(action))\n",
    "    return scratch_pad_messages\n",
    "\n",
    "def call_llm(user_input: str, chat_history: list[dict], intermediate_steps: list[AgentAction]) -> AgentAction:\n",
    "    # format the intermediate steps into a scratchpad\n",
    "    scratchpad = create_scratchpad(intermediate_steps)\n",
    "    # if the scratchpad is not empty, we add a small reminder message to the agent\n",
    "    if scratchpad:\n",
    "        scratchpad += [{\n",
    "            \"role\": \"user\",\n",
    "            \"content\": (\n",
    "                f\"Please continue, as a reminder my query was '{user_input}'. \"\n",
    "                \"Only answer to the original query, and nothing else — but use the \"\n",
    "                \"information I provided to you to do so. Provide as much \"\n",
    "                \"information as possible in the `answer` field of the \"\n",
    "                \"final_answer tool and remember to leave the contact details \"\n",
    "                \"of a promising looking restaurant.\"\n",
    "            )\n",
    "        }]\n",
    "        # we determine the list of tools available to the agent based on whether\n",
    "        # or not we have already used the search tool\n",
    "        tools_used = [action.tool_name for action in intermediate_steps]\n",
    "        tools = []\n",
    "        if \"search\" in tools_used:\n",
    "            # we do this because the LLM has a tendency to go off the rails\n",
    "            # and keep searching for the same thing\n",
    "            tools = [final_answer_schema]\n",
    "            scratchpad[-1][\"content\"] = \" You must now use the final_answer tool.\"\n",
    "        else:\n",
    "            # this shouldn't happen, but we include it just in case\n",
    "            tools = [search_schema, final_answer_schema]\n",
    "    else:\n",
    "        # this would indiciate we are on the first run, in which case we\n",
    "        # allow all tools to be used\n",
    "        tools = [search_schema, final_answer_schema]\n",
    "    # construct our list of messages\n",
    "    messages = [\n",
    "        {\"role\": \"system\", \"content\": get_system_tools_prompt(\n",
    "            system_prompt=system_prompt,\n",
    "            tools=tools\n",
    "        )},\n",
    "        *chat_history,\n",
    "        {\"role\": \"user\", \"content\": user_input},\n",
    "        *scratchpad,\n",
    "    ]\n",
    "    res = ollama.chat(\n",
    "        model=\"llama3.1:8b\",\n",
    "        messages=messages,\n",
    "        format=\"json\",\n",
    "    )\n",
    "    return AgentAction.from_ollama(res)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's try `call_llm` *with* chat history:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AgentAction(tool_name='search', tool_input={'query': 'best pizza near Rome'}, tool_output=None)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# let's fake some chat history and test\n",
    "out = call_llm(\n",
    "    chat_history=[\n",
    "        {\"role\": \"user\", \"content\": \"hi there, how are you?\"},\n",
    "        {\"role\": \"assistant\", \"content\": \"I'm good, thanks!\"},\n",
    "        {\"role\": \"user\", \"content\": \"I'm currently in Rome\"},\n",
    "        {\"role\": \"assistant\", \"content\": \"That's great, would you like any help?\"},\n",
    "    ],\n",
    "    user_input=\"yes, I'm looking for the best pizzeria near me\",\n",
    "    intermediate_steps=[]\n",
    ")\n",
    "out"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We intentionally didn't include where we are in our current `user_input`, but instead included it in the `chat_history` to confirm our agent is able to consider the chat history when building our web search tool call. It succeeded! Now we can move on to constructing our graph."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once we have our search query, we can pass it onto our `search` tool to get some results, let's try:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Visited Rome and had one of the best pizzas of my life\n",
      "Best pizza in Rome?\n",
      "Best Pizza in Rome!\n",
      "[Rec(title='Visited Rome and had one of the best pizzas of my life', description='', comments=[\"BubblefartsRock (upvotes: 202): i recently travelled to italy as well. the week after i came back, im not kidding when i say i was having hardcore cravings for the pizza from there. i live in a decent sized city and we don't have anything close to the quality level we saw there. enjoy while you can!!\", 'PopeInnocentXIV (upvotes: 82): Is that burrata in the middle?', 'hahahahaha90000 (upvotes: 155): People calling it a bread bowl probably think the crust is the texture of a New York style. \\n\\nThat crust’s texture is closer to a soufflé than bread or “pizza crust”. It’s pillowy and light and you barely have to chew to break it down. It’s divine and there’s nothing like it.']), Rec(title='Best pizza in Rome?', description='I was a little disappointed after my first experience tasting pizza after pasta and gelato were ridiculously amazing. What do you recommend? ', comments=['miclee15 (upvotes: 23): American here.  I think if OP is from the USA, Rome pizza needs to be approached differently.  I’m from NY where we think that is the best pizza in the US, people from Chicago will disagree.  Set aside the preconceived notion of what great pizza should be and enjoy the variety and flavors.   I’m in Rome now.  Went to Antico Forno Roscioli and had the most amazing porcetta pizza with potatoes on top.  I still love a NYC slice but Rome pizza is incredible at some places.  Edited for spelling', \"Sisyphus_Rock530 (upvotes: 27): \\n\\n- **Pizzeria da Remo** a Testaccio, nota per la sua base sottile e croccante, è molto popolare tra i romani. https://www.romeing.it/best-pizza-in-rome/).\\n\\n\\n- **Emma** vicino Campo de' Fiori, famosa per la sua pizza a crosta sottile e ingredienti di alta qualità (https://www.romeing.it/best-pizza-in-rome/).\\n\\n\\n- **50 Kalò** di Ciro Salvo a Termini, conosciuta per le sue pizze particolarmente idratate e leggere, con ingredienti freschi dalla Campania (https://www.romeing.it/best-pizza-in-rome/).\\n\\n\\n\\n- **Berberè** vicino ai Giardini della Villa Borghese, offre un ambiente accogliente e pizze artigianali con ingredienti freschi (https://www.romeing.it/best-pizza-in-rome/).\\n\\n\\n\\n- **Seu Pizza Illuminati** si distingue per l'uso creativo dei condimenti e per le sue sperimentazioni sui vegetali (https://www.dissapore.com/pizzerie/le-migliori-pizzerie-di-roma-gli-indirizzi-da-provar\", 'Greenlight-party (upvotes: 10): What didn’t you like about the pizza you had? That will help people hone in on a place more suited for you.\\xa0\\n\\nWhat did you like about the pasta and gelato places? What places were they? This will tell us what kind of establishments you’ve enjoyed.']), Rec(title='Best Pizza in Rome!', description='So someone posted on Reddit about how he (she?) loved the pizza in Rome and listed a few pizza places in the post. I took one of the suggestions (thank you dear Redditor!) and went to Seu Pizza Illuminati. Hands down, the best pizza I’ve ever had. So, to anyone looking for good pizza, from one Redditor to another, a huge recommendation to this place! ', comments=['StrictSheepherder361 (upvotes: 58): ...if one like Neapolitan-type pizza. We Romans tend to prefer Roman-kind pizza (crispy, subtler, without that cornice that I personally find excessive).', 'Tezracca (upvotes: 10): i also love spider pizza, one of the best', \"Famous_Release22 (upvotes: 19): **Romana:**\\n\\nA'Rota pizzeria romanesca - via di torpignattara, 190\\n\\n180g pizzeria romana - via Gennazzano, 32/34\\n\\nL'elementare - via Benedetta, 23\\n\\nPizzeria Clementina Via della Torre Clementina, 158 Fiumicino ( near the Airport)\\n\\n**Napoletana**\\n\\nSeu Illuminati - via Angelo Borgoni, 10-18\\n\\n50 kalo'di Ciro Salvo - via Flavia, 3b\"])]\n"
     ]
    }
   ],
   "source": [
    "results = search(**out.tool_input)\n",
    "print(results)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now have our results! Each of these is pretty high level, there is not much detail as they only represent search page result descriptions. So now, we must decide which links look most promising — we can do that by passing these results onwards to another LLM that decides which result we should get more information from."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Graph Nodes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have defined the different logical components of our graph, but we need to execute them in a langgraph-friendly manner — for that they must consume our `AgentState` and return modifications to that state. We will do this for all of our components via three functions:\n",
    "\n",
    "* `run_oracle` will handle running our oracle LLM.\n",
    "* `router` will handle the *routing* between our oracle and tools.\n",
    "* `run_tool` will handle running our tool functions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "def run_oracle(state: TypedDict):\n",
    "    print(\"run_oracle\")\n",
    "    chat_history = state[\"chat_history\"]\n",
    "    out = call_llm(\n",
    "        user_input=state[\"input\"],\n",
    "        chat_history=chat_history,\n",
    "        intermediate_steps=state[\"intermediate_steps\"]\n",
    "    )\n",
    "    return {\n",
    "        \"intermediate_steps\": [out]\n",
    "    }\n",
    "\n",
    "def router(state: TypedDict):\n",
    "    print(\"router\")\n",
    "    # return the tool name to use\n",
    "    if isinstance(state[\"intermediate_steps\"], list):\n",
    "        return state[\"intermediate_steps\"][-1].tool_name\n",
    "    else:\n",
    "        # if we output bad format go to final answer\n",
    "        print(\"Router invalid format\")\n",
    "        return \"final_answer\"\n",
    "\n",
    "# we use this to map tool names to tool functions\n",
    "tool_str_to_func = {\n",
    "    \"search\": search,\n",
    "    \"final_answer\": final_answer\n",
    "}\n",
    "\n",
    "def run_tool(state: TypedDict):\n",
    "    # use this as helper function so we repeat less code\n",
    "    tool_name = state[\"intermediate_steps\"][-1].tool_name\n",
    "    tool_args = state[\"intermediate_steps\"][-1].tool_input\n",
    "    print(f\"run_tool | {tool_name}.invoke(input={tool_args})\")\n",
    "    # run tool\n",
    "    out = tool_str_to_func[tool_name](**tool_args)\n",
    "    action_out = AgentAction(\n",
    "        tool_name=tool_name,\n",
    "        tool_input=tool_args,\n",
    "        tool_output=str(out),\n",
    "    )\n",
    "    if tool_name == \"final_answer\":\n",
    "        return {\"output\": out}\n",
    "    else:\n",
    "        return {\"intermediate_steps\": [action_out]}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We construct our graph using `add_nodes`, `add_edge`, and `add_conditional_edges`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langgraph.graph import StateGraph, END\n",
    "\n",
    "graph = StateGraph(AgentState)\n",
    "\n",
    "graph.add_node(\"oracle\", run_oracle)\n",
    "graph.add_node(\"search\", run_tool)\n",
    "graph.add_node(\"final_answer\", run_tool)\n",
    "\n",
    "graph.set_entry_point(\"oracle\")  # insert query here\n",
    "\n",
    "graph.add_conditional_edges(  # - - - >\n",
    "    source=\"oracle\",  # where in graph to start\n",
    "    path=router,  # function to determine which node is called\n",
    ")\n",
    "\n",
    "# create edges from each tool back to the oracle\n",
    "for tool_obj in [search_schema, final_answer_schema]:\n",
    "    tool_name = tool_obj[\"function\"][\"name\"]\n",
    "    if tool_name != \"final_answer\":\n",
    "        graph.add_edge(tool_name, \"oracle\")  # ————————>\n",
    "\n",
    "# if anything goes to final answer, it must then move to END\n",
    "graph.add_edge(\"final_answer\", END)\n",
    "\n",
    "runnable = graph.compile()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To view the graph we can generate a mermaid graph like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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zpfdbu+wb01NtZYundeubcKESfrzn59QfX29nn32cb322vNyueoCXv/II88pK2u077i2tkarVr2mN998WXl5OZ3WOW/eQi1b9oOgobUjXq9Xn376sV57bYU2b97QYd/4+ATNnbtQixZdoMzM4d1+r65yu91atepVvfTSv1RQkNdh3xkzZumHP7xJw4ZlGVYPAPQGAicAAAOYx+PR448/oJdf/neX+hcU5Olvf7tPr776nG699Q8aPXpc0L5tRzbbtpWVleo3v/mldu7cFvTaCRMm+cKmx+PRc889oaeffrRLNR6u85ln/q73339bP/vZrZo8eVqXr92//xv96U93aPfur7vUv6KiXC+//G+9/PK/df75l+iSS65STExsl9+vK/bs2ak777yl06B52MaN67Rx4zpddtm1Wrr0UkVERPRqPQDQW5jDCQDAANXQ0KC77/5Vl8NmWwUFefrFL36obdu+7NZ1bnejfve7mzsMm5J03nkX+17X1FR3K2weWed///d1OnSooEv9N25cp+uuu7jLYfNIL7/8bxUVFfbo2mA++eQj/eQnl3Y5bLb11FOP6PrrL1FpaUmv1gQAvYXACQDAAPX8809q3boPgp6fNu1kzZ59utLSMgKed7nqdPfdv1J9fX2X33P//m+0ffuWdm1OZ6QmTZoipzNSUssjqqeccprvfHx8ghYtuqDL7xHI3//+l077bNmyWbfd9rMO+6SlZbSr9UgLFpzb4ahvd+3YsVW33/7LoOfj4xM0fPhIDR8+MmifvLwcPfjgPb1WEwD0Jh6pBQBgACoqKtQzzzwW8NyvfnW3Zs6cI6u19WNAaWmxfv/7W/XVV5vb9S0pKdLKlS9q6dLvd7uGpKQU/frXf9TYscfIYrHI7XZr9eqVcjicstls7fpedNEP9OabL/mO58w5U7Nnn6709GFKS8uU3W5XcfEhbd68QY8+er/fvNC1a9/T4sUX6rjjTghYS2lpse666/8FPJeWlqEbbrhFEyZMUlRUdJtrSrRr1za9+uoKbdnymZKSUnTttR0H1u4oLS3R7bf/IuC5BQvO1WWXXavExGRfW2Njoz77bL3+/Oe7VFFR3q7/+vUfau3a9zR79um9Vh8A9AYCJwAAA9ATTzzk1+Z0Rur3v/+rJkyY5HcuMTFZd931gP7857u0evXKdueeeeYxzZ+/uFvzFseNO1Z3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tq3oOKXGwklERERERKQmOnbsiI4dO4qOoTIaO6WWiIiIiIiI1BsLJxEREREREZUJFk4iIiIiIiIqEyycREREREREVCa4aRAREREREZEa2bt3L65evYqkpCSMGzcOLi4uoiOVGO9wEhERERERqZGzZ89iz549OHXqFB48eCA6TqmwcBIREREREakROzs76TopKUlgktJj4SQiIiIiIlIjhQvn06dPBSYpPRZOIiIiIiIiNVK4cCYnJwtMUnosnERERERERGrE1tZWutb0KbXcpZaIiIiIiEiNNGvWDJs3b4adnR0cHR1FxykVFk4iIiIiIiI1YmVlBSsrK9ExVIJTaomIiIiIiKhMsHASERERERFRmWDhJCIiIiIiojLBwklERERERERlgoWTiIiIiIhIzfTv3x8eHh7w8PDA48ePRccpMRZOIiIiIiIiNWNmZiZdy2QygUlKh4WTiIiIiIhIzRQunBkZGQKTlA4LJxERERERkZoxNzeXrlk4iYiIiIiISGVMTU2la02eUmsoOgAREREREREps7S0hI2NDezs7JTKp6Zh4SQiIiIiIlIzgYGBCAwMFB2j1DilloiIiIiIiMoECycRERERERGVCRZOIiIiIiIiKhMsnERERERERFQmuGkQERERERGRmklOTkZ0dDQAwMHBAS4uLoITlQzvcBIREREREamZ69evY+TIkRg5ciRCQ0NFxykxFk4iIiIiIiI1U6FCBek6JydHYJLSYeEkIiIiIiJSMyycREREREREVCYMDV9st5ObmyswSemwcBIREREREakZbbnDyV1qiYiIiIiI1IylpSXat28POzs71KtXT3ScEmPhJCIiIiIiUjNOTk5YunSp6Bilxim1REREREREVCZYOImIiIiIiKhMsHASERERERFRmWDhJCIiIiIiojLBTYOIiIiIiIjU0Nq1awEA5ubm8Pf3F5ymZFg4iYiIiIiI1Ex2djZCQkIAAA4ODhpbODmlloiIiIiISM0YGBhI13l5eQKTlA7vcBK9o6dPE5GdnSU9NjY2hr29o8BERKTunj1LgkKhgL29g+goakculyMhIV5pzMbGDmZmZoISERGpB339F/cGFQqFwCSlw8JJ9I5GjfJDcvIzpbFDhy4ISkNE6igrKwu//bYNN25cw7///i39zjA1NUOtWnVRo4Ybunf3RbVqLkW+9tGjB0hM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cXrnnXdUWFhodEkuQ+AEAABwIh8fHw0cONB6OzY21sBqALij3377TRkZGZKktm3bqmHDhgZX5DoETgAAACcbPHiwdXvt2rUGVgLAHa1fv9663b9/fwMrcT0CJwAAgJNdc801CggIkCTt3r1bSUlJBlcEwJ2sXr3aul36B6q6iMAJAADgAgMGDLBuL1682MBKALiT3NxctWvXTiEhIYqJiVHnzp2NLsmlvCwWi8XoIgAAAOqauLg4TZo0SZIUFRWl5cuXy2QyGVwVAHeSkJCgmJgYo8twKVo4AQAAXKB3795q3ry5JCklJUXr1q0zuCIA7qauh02JwAkAAOAyt99+u3X7yy+/NLASADAGgRMAAMBFRo4cKX9/f0nS9u3bFR8fb3BFAFC7CJwAAAAuEhISohEjRlhvv//++wZWA8BIubm5ys7ONrqMWkfgBAAAcKGxY8dat5cvX65jx44ZWA0AoyxfvlwDBw7UE088od9//93ocmoNgRMAAMCF2rVrp759+0qSLBaL3n33XYMrAmCEhQsXSpJiY2OVmJhocDW1h8AJAADgYlOmTLFur1mzRgcPHjSwGgC17ZdfftGpU6ckSZGRkWXW6a3rCJwAAAAudskll+i6666z3n777bcNrAZAbfviiy+s27fffru8vetPDKs/rxQAAMBAkydPlo+PjyTp559/1t69ew2uCEBtSExM1IYNGyRJPj4+uuWWWwyuqHYROAEAAGpBs2bNylxovvbaayosLDSwIgC1wWw2a+DAgZKkESNGqEGDBgZXVLu8LBaLxegiAAAA6oOMjAzdcMMNysvLkyRNnTpVd9xxh8FVAagNR48elbe3t1q1amV0KbWKFk4AAIBa0qBBA02ePNl6e86cOTp9+rSBFQGoLW3atKl3YVMicAIAANSqcePGqVOnTpKk8+fP64UXXjC4IgBwHQInAABALfLy8tJLL71knUBo586d+u677wyuCgBcg8AJAABQy1q2bKn777/fevvf//630tPTDawIgDPt27evzFIo9RmBEwAAwADjx49X27ZtJUnZ2dl65plnxFyOQN0wY8YMzZw5U2PGjNGRI0eMLsdQBE4AAAADmEwmvfjii9YF4Ldu3aq5c+caXBWAmlq6dKn27dsnSTp58qTCwsIMrshYBE4AAACDdOzYUZMmTbLenjdvnrZs2WJgRQBqIjU1VbNn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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import nest_asyncio\n",
    "from IPython.display import Image, display\n",
    "from langchain_core.runnables.graph import CurveStyle, MermaidDrawMethod, NodeStyles\n",
    "\n",
    "nest_asyncio.apply()  # Required for Jupyter Notebook to run async functions\n",
    "\n",
    "display(\n",
    "    Image(\n",
    "        runnable.get_graph().draw_mermaid_png(\n",
    "            curve_style=CurveStyle.LINEAR,\n",
    "            node_colors=NodeStyles(first=\"#ffdfba\", last=\"#baffc9\", default=\"#fad7de\"),\n",
    "            wrap_label_n_words=9,\n",
    "            output_file_path=None,\n",
    "            draw_method=MermaidDrawMethod.PYPPETEER,\n",
    "            background_color=\"white\",\n",
    "            padding=10,\n",
    "        )\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Testing the Agent"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Our agent has now been constructed so we can test it. First, let's check for the best pizza in Rome:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "run_oracle\n",
      "router\n",
      "run_tool | search.invoke(input={'query': 'best pizza in Rome'})\n",
      "Best pizza in Rome?\n",
      "Visited Rome and had one of the best pizzas of my life\n",
      "Best Pizza in Rome!\n",
      "run_oracle\n",
      "router\n",
      "run_tool | final_answer.invoke(input={'answer': 'Based on your question, I would recommend trying Seu Pizza Illuminati in Rome for an amazing pizza experience. They are known for their creative use of condiments and experiments with vegetables. If you prefer a Neapolitan-style pizza, Pizzeria da Remo or Emma might be the perfect choice for you. Both places have received great reviews from locals and visitors alike.', 'phone_number': '', 'address': ''})\n"
     ]
    }
   ],
   "source": [
    "out = runnable.invoke({\n",
    "    \"input\": \"where is the best pizza in rome?\",\n",
    "    \"chat_history\": [],\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We extract the answer:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'answer': 'Based on your question, I would recommend trying Seu Pizza Illuminati in Rome for an amazing pizza experience. They are known for their creative use of condiments and experiments with vegetables. If you prefer a Neapolitan-style pizza, Pizzeria da Remo or Emma might be the perfect choice for you. Both places have received great reviews from locals and visitors alike.',\n",
       " 'phone_number': '',\n",
       " 'address': ''}"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "out[\"output\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We are recommended [Seu Pizza Illuminati](https://maps.app.goo.gl/RMSdTUpH8D3oQETUA), a seemingly notorious pizzeria known for their less traditional and more experimental Neapolitan pizzas."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
